Showing Camera Shutter Effect
Developing the camera shutter effect program with Numpy and Tkinter.
We'll cover the following
These are the libraries that you will be using.
import tkinter as tk
import numpy as np
from PIL import Image, ImageTk
Getting set up#
This program will use conic sections to compute the ellipses that will represent the propellers. Here is a very high-level mathematical explanation: the absolute value of a complex plane in the third dimension is a cone. Slicing the cone in planes parallel to the x-y plane results in a circle. Anything from the circle down to the Z = 0 plane is a disk. Adding multiple cones offset from the origin results in a solid ellipse, and moving the location of the ellipse around the origin X amount of times results in X number of blades in a propeller. Conic sections continue to haunt you, and this time, they are complex! This program glosses over some difficult topics like representing a two-dimensional array with one variable with Numpy, creating geometric shapes from simple expressions of complex numbers, and using addition and multiplication to translate the geometric shapes.
First, you need to get Tkinter configured. You will create a Tk instance that is the base Tkinter instance, get the “stage” ready that is where the image goes and set the stage height and number of propeller blades.
root = tk.Tk()
stage = tk.Label(root)
stage.pack()
height = 300
num_propeller_blades = 4
Spinning the propeller#
The next snippet creates a meshgrid that returns a three-dimensional array; this array helps you to create the 3D plane that will create the spinning propeller. You also establish the bent propeller image from the complex plane that will start out blank (zeros) and eventually be filled in when the line overlaps the spinning propeller.
x, y = np.ogrid[-height/2: height/2, -height/2: height/2]
plane = x - 1j * y
bentprop = np.zeros_like(plane, dtype=np.bool)
You can learn more about ogrid() here [2]. The - 1 j means the propeller will spin clockwise; change it to + 1 j for counter-clockwise rotation. For each “row” in your frame height (300 pixels), you need to sweep the shutter down one pixel, create the propeller blades, rotate the propeller blades, and “remember” where the shutter line touched the spinning propeller blade.
Creating the stage#
Now that you have all of the image data, you need to convert the arrays into an actual image using Pillow, and then update the stage with the new image.
This snippet needs to occur for each frame update too, so it needs to be included in the first for loop:
Seeing the results#
Lastly, you need to make sure the GUI snaps to the front, and you will give the new window a nice title.
root.lift()
root.attributes('-topmost', True)
root.after_idle(root.attributes, '-topmost', False)
root.title('{} blade propeller camera effect'.format(num_propeller_blades))
root.mainloop()
Here is the full code. To run it, click the blue “Run” button, and then click the link after Your app can be found at: below the code segment.
/
Here is a gif of the result, since Educative’s VNC version only runs once:
The red represents every time that a propeller blade interacted with the blue line. If a picture were to be taken, the photograph would look like the red bird/blob and not the 4-bladed propeller. You can vary the number of blades and the rotation direction to see how the shutter image changes. The propeller starts getting pretty fat after 7 blades, and you’ll be hard-pressed to find a propeller that has more than 6 blades. This graphic easily explains why the propellers look like they’re made of rubber when on camera: the shutter only picks up some of the blades, some of the time, so the resulting image is not a faithful representation of the actual propeller rotation.
Introduction to Advanced Numpy Usage
Conclusion for Advanced Modeling